#include "widget.h"
#include "ui_widget.h"

QByteArray Widget::controlResponse = {0};

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    ,ui(new Ui::Widget),compoundFlag(0)
{
    ui->setupUi(this);
    communicationManager = new CommunicationManager(this);
    protocol = new ProtocolHandler(this);
    checkTimer = new QTimer;
    relationTimer = new QTimer;
    checkResponseTimer = new QTimer;
    checkComResponseTimer = new QTimer;
    checkFlashResponseTimer = new QTimer;
    checkExistResponseTimer = new QTimer;
    compoundTimer = new QTimer;
    checkComTimer = new QTimer;

    loadFlashTimer = new QTimer;
    loadFristDataTimer = new QTimer;
    loadLastDataTimer = new QTimer;

    promptMessage = nullptr;


    //连接控制类响应超时函数
    connect(checkTimer,&QTimer::timeout,
            this,&Widget::handleControlTimeout);
    //连接每间隔10MS发送一次通信命令
    connect(relationTimer,&QTimer::timeout,
            this,&Widget::relationTimerout);
    //连接循环接受 复位 响应的信号和槽
    connect(checkResponseTimer,&QTimer::timeout,
            this,&Widget::checkResponseTimerout);
    //连接循环接受 通信 响应的信号和槽
    connect(checkComResponseTimer,&QTimer::timeout,
            this,&Widget::checkComResponseTimerout);
    //连接循环接受 清除Flash 响应的信号和槽
    connect(checkFlashResponseTimer,&QTimer::timeout,
            this,&Widget::checkFlashResponseTimerout);
    //连接循环接受 测试存在 响应的信号和槽
    connect(checkExistResponseTimer,&QTimer::timeout,
            this,&Widget::checkExistResponseTimerout);

    connect(compoundTimer, &QTimer::timeout,
            this, &Widget::checkCompoundResponse);

    //连接接收到数据后更新textEdit_data_log的显示界面
    connect(communicationManager,&CommunicationManager::dataUiUpdata,
            this,&Widget::displayDataInLog);




    //连接 写入数据接收清空flash 命令的响应
    connect(loadFlashTimer,&QTimer::timeout,
            this,&Widget::checkFlashDataResponse);

    //连接 写入数据接收第一个数据包 的响应
    connect(loadFristDataTimer,&QTimer::timeout,
            this,&Widget::checkFirstPacketResponse);
     //连接 写入数据接收最后一个数据包 的响应
    connect(loadLastDataTimer,&QTimer::timeout,
            this,&Widget::checkLastPackResponse);




    // 连接每一个复位输入框的文本更改信号到同一槽，进行实时更新
    connect(ui->lineEdit_station, &QLineEdit::editingFinished, this, &Widget::rest_updateCRC);
    connect(ui->lineEdit_rest_description, &QLineEdit::editingFinished, this, &Widget::rest_updateCRC);
    connect(ui->lineEdit_rest_dat_1, &QLineEdit::editingFinished, this, &Widget::rest_updateCRC);
    connect(ui->lineEdit_rest_dat_2, &QLineEdit::textChanged, this, &Widget::rest_updateCRC);

    // 连接每一个通讯输入框的文本更改信号到同一槽，进行实时更新
    connect(ui->lineEdit_station, &QLineEdit::editingFinished, this, &Widget::com_updateCRC);
    connect(ui->lineEdit_com_des, &QLineEdit::editingFinished, this, &Widget::com_updateCRC);
    connect(ui->lineEdit_com_data_1, &QLineEdit::editingFinished, this, &Widget::com_updateCRC);
    connect(ui->lineEdit_com_data_2, &QLineEdit::textChanged, this, &Widget::com_updateCRC);

    //连接每一个Flash输入框的文本更改信号到同一槽，进行实时更新
    connect(ui->lineEdit_station, &QLineEdit::editingFinished, this, &Widget::flash_updateCRC);
    connect(ui->lineEdit_flash_description, &QLineEdit::editingFinished, this, &Widget::flash_updateCRC);
    connect(ui->lineEdit_falsh_data_1, &QLineEdit::editingFinished, this, &Widget::flash_updateCRC);
    connect(ui->lineEdit_falsh_data_2, &QLineEdit::textChanged, this, &Widget::flash_updateCRC);

    //连接每一个测试存在输入框的文本更改信号到同一槽，进行实时更新
    connect(ui->lineEdit_station, &QLineEdit::editingFinished, this, &Widget::exist_updateCRC);
    connect(ui->lineEdit_exist_description, &QLineEdit::editingFinished, this, &Widget::exist_updateCRC);
    connect(ui->lineEdit_exist_data_1, &QLineEdit::editingFinished, this, &Widget::exist_updateCRC);
    connect(ui->lineEdit_exist_data_2, &QLineEdit::textChanged, this, &Widget::exist_updateCRC);


    compoundElapsedTimer.start();//开启复合指令接收复为响应的计时器

    //加载上次写入的数据
    loadSettings();

}

Widget::~Widget()
{
    qDebug()<<"程序正在关闭";
    //保存输入的数据
    saveSettings();
    qDebug()<<"已保存现有数据";

    qDebug()<<"正在关闭定时器";
    // 定时器停止并删除
    stopAndDeleteTimer(checkTimer);

    stopAndDeleteTimer(relationTimer);

    stopAndDeleteTimer(checkResponseTimer);

    stopAndDeleteTimer(checkComResponseTimer);

    stopAndDeleteTimer(checkFlashResponseTimer);

    stopAndDeleteTimer(checkExistResponseTimer);

    stopAndDeleteTimer(compoundTimer);

    stopAndDeleteTimer(loadLastDataTimer);

    stopAndDeleteTimer(loadFlashTimer);

    stopAndDeleteTimer(checkComTimer);

    stopAndDeleteTimer(loadFristDataTimer);

    if (promptMessage) {
        promptMessage->close();
    }

    delete ui; // 删除ui最后，因为它可能在其他地方被使用
    qDebug()<<"程序已经关闭";

}
//连接串口按钮
void Widget::on_pushButton_connect_clicked()
{
    openSerialPort();
}

//建立通信
void Widget::openSerialPort()
{
    QString comPort = ui->lineEdit_com->text();
    int rate = ui->lineEdit_rate->text().toInt();
    QSerialPort::Parity parity = static_cast<QSerialPort::Parity>(ui->lineEdit_parity_bit->text().toInt());
    QSerialPort::DataBits dataBits = static_cast<QSerialPort::DataBits>(ui->lineEdit_data_bit->text().toInt());
    QSerialPort::StopBits stopBits = static_cast<QSerialPort::StopBits>(ui->lineEdit_stop_bit->text().toInt());

    communicationManager->setupSerialPort(comPort, rate, parity, dataBits, stopBits);
}

//控制类响应的超时函数
void Widget::handleControlTimeout()
{
    if(checkTimer->isActive())
    {
        checkTimer->stop();
        qDebug()<<"checkTimer因时间超时关闭";
    }
    QMessageBox::critical(nullptr, "超时警告", "已超时！");
}

//实现每10ms发送一次通信命令的槽函数
void Widget::relationTimerout()
{
    // 检查是否接收到正确的控制响应
    if (com_data == controlResponse) {
        qDebug() << "接收到正确响应，停止定时器并不再下发报文";
        relationTimer->stop(); // 停止 relationTimer
        communicationManager->stopSendData(); // 停止发送数据
        QMessageBox::information(nullptr, "连接成功", "通信已建立"); // 显示连接成功的消息框
    } else {
        // 如果未接收到正确响应，继续发送
        communicationManager->sendData(com_data);
    }

    // 检查 relationTimer 是否超时
    if (compoundElapsedTimer.elapsed() >= 30000) {
        qDebug() << "relationTimer 超时，未接收到正确响应";
        relationTimer->stop(); // 停止 relationTimer
        communicationManager->stopSendData(); // 停止发送数据
    }
}
//实现循环接收复位响应是否符合的超时函数
void Widget::checkResponseTimerout()
{
    if (rest_data == controlResponse)
    {
        qDebug() << "成功响应";
        checkResponseTimer->stop(); // 立即停止检查响应的计时器
        checkTimer->stop(); // 立即停止5秒超时计时器
        if(checkTimer->isActive())
        {
            qDebug()<<"发送完复位命令，checkTimer没有关闭";
        }
    }

}
//实现循环接收 通信 响应是否符合的超时函数
void Widget::checkComResponseTimerout()
{
    if (com_data == controlResponse)
    {
        qDebug() << "成功响应";
        checkComResponseTimer->stop(); // 立即停止检查响应的计时器
        checkTimer->stop(); // 立即停止5秒超时计时器
        if(checkTimer->isActive())
        {
            qDebug() << "发送完通讯命令，checkTimer没有关闭";
        }
    }

}
//实现循环接收 清除Flash 响应是否符合的超时函数
void Widget::checkFlashResponseTimerout()
{
    if (flash_data == controlResponse)
    {
        qDebug() << "成功响应";
        checkFlashResponseTimer->stop(); // 立即停止检查响应的计时器
        checkTimer->stop(); // 立即停止5秒超时计时器
        if(checkTimer->isActive())
        {
            qDebug()<<"发送完Flash命令，checkTimer没有关闭";
        }
    }

}
//实现循环接收 测试存在 响应是否符合的超时函数
void Widget::checkExistResponseTimerout()
{
    qDebug() << "checkExistResponseTimerout: exist_data: " << exist_data.toHex();
    qDebug() << "checkExistResponseTimerout: controlResponse: " << controlResponse.toHex();

    if (exist_data == controlResponse)
    {
        qDebug() << "成功响应";
        checkExistResponseTimer->stop(); // 立即停止检查响应的计时器
        checkTimer->stop(); // 立即停止5秒超时计时器
        if(checkTimer->isActive())
        {
            qDebug()<<"发送完测试存在命令，checkTimer没有关闭";
        }
    }
}
// 复合指令1 接收复位指令的超时函数
void Widget::checkCompoundResponse()
{
    // 检查是否接收到复位响应
    if (rest_data == controlResponse) {
        controlResponse.clear();
        compoundFlag++; // 增加复位响应计数器
        if (compoundFlag == 2) {
            // 如果接收到两次复位响应
            checkComTimer->stop(); // 停止 checkTimer    
            compoundTimer->stop(); // 停止 compoundTimer           

            qDebug() << "接收复位响应成功，正在准备通信....";
            QThread::msleep(3); // 先等待3ms

            relationTimer->start(1000); // 启动 relationTimer，每10毫秒检查一次
            QTimer::singleShot(30000, this, [this]() { relationTimer->stop(); }); // 30秒后停止 relationTimer
        }
    }
    if (compoundElapsedTimer.elapsed() >= 60000) {
        qDebug() << "未接收到复位响应";
        checkComTimer->stop(); // 停止 checkTimer        
        compoundTimer->stop(); // 停止 compoundTimer        
    }
}

//点击复位按钮 发送 复位数据
void Widget::on_pushButton_restoration_clicked()
{
    communicationManager->sengFlagTrue();
    if(protocol->validateMessageFormat(rest_data))
        qDebug() << "即将发送的data: " << rest_data.toHex();
    communicationManager->sendData(rest_data);
    //将当前命令显示在数据日志的最上方
    displayDataInLog(rest_data);
    checkTimer->start(5000);//等待5秒，接收响应
    checkResponseTimer->start(100);//每100ms检查一次是否接收到响应
}
//复位命令CRC计算
void Widget::rest_updateCRC()
{
    update_rest_ArrayData();
}
// 更新复位数组数据的方法
void Widget::update_rest_ArrayData()
{
    rest_data.clear(); // 先清空数组

    bool ok;
    quint8 station = ui->lineEdit_station->text().toUInt(&ok, 16);
    quint8 sid = ui->lineEdit_rest_description->text().toUInt(&ok, 16);
    quint16 data1 = ui->lineEdit_rest_dat_1->text().toUInt(&ok, 16);
    quint16 data2 = ui->lineEdit_rest_dat_2->text().toUInt(&ok, 16);

    // 以小端方式存储数据
    rest_data.append(static_cast<char>(station));
    rest_data.append(static_cast<char>(sid));

    rest_data.append(static_cast<char>(data1 & 0xFF)); // 低字节
    rest_data.append(static_cast<char>((data1 >> 8) & 0xFF)); // 高字节

    rest_data.append(static_cast<char>(data2 & 0xFF)); // 低字节
    rest_data.append(static_cast<char>((data2 >> 8) & 0xFF)); // 高字节

    // 计算CRC
    unsigned short crc = protocol->publicCalculateCRC(rest_data);
    // 使用小端格式存储CRC
    rest_data.append(static_cast<char>(crc & 0xFF)); // 先存储低字节
    rest_data.append(static_cast<char>((crc >> 8) & 0xFF)); // 然后存储高字节

    qDebug() << "复位命令数组刚写进数组的数据： "<<rest_data.toHex(); // 打印com_data的十六进制表示
}



//点击 更新 复位命令
void Widget::on_Button_refres_clicked()
{
    qDebug()<<"点击复位更新时的rest_data： "<<this->rest_data.toHex();
    if(protocol->validateMessageFormat(rest_data))
    {
        // 将结果显示到Label，每个字节之间加空格
        QString displayStr;
        for (char byte : rest_data) {
            displayStr += QString("%1 ").arg(static_cast<unsigned char>(byte), 2, 16, QChar('0'));
        }
        ui->label_rest_show->setText(displayStr.toUpper());
    }
    qDebug()<<"验证复位更新后的rest_data： "<<this->rest_data.toHex();
}

//停止定时器，用于控制类响应）
void Widget::stopCheckTimer()
{
    if(checkTimer->isActive())
    {
        qDebug()<<"关闭checkTimer定时器";
        checkTimer->stop();
    }
}

// 获取时间戳并和响应数组一起显示在指定控件上  ui->textEdit_data_log
void Widget::displayDataInLog(const QByteArray &data)
{
    // 获取当前时间的时间戳
    QString timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");

    // 将数据数组格式化为十六进制字符串
    QString dataStr;
    for (char byte : data) {
        dataStr += QString("%1 ").arg(static_cast<unsigned char>(byte), 2, 16, QChar('0'));
    }

    // 组合时间戳和数据字符串，使用HTML格式来设置颜色和样式
    QString logEntry = QString("<b><font color='black'>%1</font></b>: <b><font color='green'>%2</font></b>")
                           .arg(timestamp, dataStr);

    // 获取当前日志内容
    QString currentLog = ui->textEdit_data_log->toPlainText();

    // 将新日志条目添加到最下方
    ui->textEdit_data_log->append(logEntry);

    // 滚动到最下方
    QTextCursor cursor = ui->textEdit_data_log->textCursor();
    cursor.movePosition(QTextCursor::End);
    ui->textEdit_data_log->setTextCursor(cursor);
}

//点击通信按钮
void Widget::on_pushButton_common_clicked()
{
    communicationManager->sengFlagTrue();
    if(protocol->validateMessageFormat(com_data))
        qDebug() << "即将发送的data: " << com_data.toHex();
    communicationManager->sendData(com_data);
    //将当前命令显示在数据日志的最上方
    displayDataInLog(com_data);
    checkTimer->start(5000);//等待5秒，接收响应
    checkComResponseTimer->start(10);//每间隔10ms检查是否接收到响应

}

//点击通信 更新 命令按钮
void Widget::on_Button_com_refres_clicked()
{
    if(protocol->validateMessageFormat(com_data))
    {
        // 将结果显示到Label，每个字节之间加空格
        QString displayStr;
        for (char byte : com_data) {
            displayStr += QString("%1 ").arg(static_cast<unsigned char>(byte), 2, 16, QChar('0'));
        }
        ui->label_com_show->setText(displayStr.toUpper());
    }
}
//通讯命令CRC计算
void Widget::com_updateCRC()
{
    update_com_ArrayData();
}
// 更新通讯数组数据的方法
void Widget::update_com_ArrayData()
{
    com_data.clear(); // 先清空数组

    bool ok;
    quint8 station = ui->lineEdit_station->text().toUInt(&ok, 16);
    quint8 sid = ui->lineEdit_com_des->text().toUInt(&ok, 16);
    quint16 data1 = ui->lineEdit_com_data_1->text().toUInt(&ok, 16);
    quint16 data2 = ui->lineEdit_com_data_2->text().toUInt(&ok, 16);

    // 以小端方式存储数据
    com_data.append(static_cast<char>(station));
    com_data.append(static_cast<char>(sid));

    com_data.append(static_cast<char>(data1 & 0xFF)); // 低字节
    com_data.append(static_cast<char>((data1 >> 8) & 0xFF)); // 高字节

    com_data.append(static_cast<char>(data2 & 0xFF)); // 低字节
    com_data.append(static_cast<char>((data2 >> 8) & 0xFF)); // 高字节

    // 计算CRC
    unsigned short crc = protocol->publicCalculateCRC(com_data);
    // 使用小端格式存储CRC
    com_data.append(static_cast<char>(crc & 0xFF)); // 先存储低字节
    com_data.append(static_cast<char>((crc >> 8) & 0xFF)); // 然后存储高字节
}
// 更新flash数组数据的方法
void Widget::update_flash_ArrayData()
{
    flash_data.clear(); // 先清空数组

    bool ok;
    quint8 station = ui->lineEdit_station->text().toUInt(&ok, 16);
    quint8 sid = ui->lineEdit_flash_description->text().toUInt(&ok, 16);
    quint16 data1 = ui->lineEdit_falsh_data_1->text().toUInt(&ok, 16);
    quint16 data2 = ui->lineEdit_falsh_data_2->text().toUInt(&ok, 16);

    // 以小端方式存储数据
    flash_data.append(static_cast<char>(station));
    flash_data.append(static_cast<char>(sid));

    flash_data.append(static_cast<char>(data1 & 0xFF)); // 低字节
    flash_data.append(static_cast<char>((data1 >> 8) & 0xFF)); // 高字节

    flash_data.append(static_cast<char>(data2 & 0xFF)); // 低字节
    flash_data.append(static_cast<char>((data2 >> 8) & 0xFF)); // 高字节

    // 计算CRC
    unsigned short crc = protocol->publicCalculateCRC(flash_data);
    // 使用小端格式存储CRC
    flash_data.append(static_cast<char>(crc & 0xFF)); // 先存储低字节
    flash_data.append(static_cast<char>((crc >> 8) & 0xFF)); // 然后存储高字节

    qDebug() << "清除FLASH命令数组刚写进数组的数据： "<<flash_data.toHex();
}

//点击清除Flash按钮
void Widget::on_Button_Falsh_clicked()
{
    communicationManager->sengFlagTrue();
    if(protocol->validateMessageFormat(flash_data))
        qDebug() << "即将发送的data: " << flash_data.toHex();
    communicationManager->sendData(flash_data);
    //将当前命令显示在数据日志的最上方
    displayDataInLog(flash_data);
    checkTimer->start(5000);//等待5秒，接收响应
    checkFlashResponseTimer->start(10);
}
//点击 更新 Flash命令显示
void Widget::on_Button_flash_refres_clicked()
{
    qDebug()<<"点击清除FALSH更新时的flash_data： "<<this->flash_data.toHex();
    if(protocol->validateMessageFormat(flash_data))
    {
        // 将结果显示到Label，每个字节之间加空格
        QString displayStr;
        for (char byte :flash_data) {
            displayStr += QString("%1 ").arg(static_cast<unsigned char>(byte), 2, 16, QChar('0'));
        }
        ui->label_Flsh_show->setText(displayStr.toUpper());
    }
}
//清除Flash命令CRC计算
void Widget::flash_updateCRC()
{
    update_flash_ArrayData();
}


//点击测试存在按钮
void Widget::on_Button_exist_clicked()
{
    communicationManager->sengFlagTrue();
    if(protocol->validateMessageFormat(exist_data))
        qDebug() << "即将发送的data: " << exist_data.toHex();
    communicationManager->sendData(exist_data);
    //将当前命令显示在数据日志的最上方
    displayDataInLog(exist_data);
    checkTimer->start(5000);//等待5秒，接收响应
    checkExistResponseTimer->start(500);

}
//测试存在 更新 命令显示
void Widget::on_Button_exist_refres_clicked()
{
    qDebug()<<"点击清除FALSH更新时的flash_data： "<<this->exist_data.toHex();
    if(protocol->validateMessageFormat(exist_data))
    {
        // 将结果显示到Label，每个字节之间加空格
        QString displayStr;
        for (char byte :exist_data) {
            displayStr += QString("%1 ").arg(static_cast<unsigned char>(byte), 2, 16, QChar('0'));
        }
        ui->label_exist_show->setText(displayStr.toUpper());
    }
}
//测试存在命令CRC计算
void Widget::exist_updateCRC()
{
    update_exist_ArrayData();
}
//更新测试存在数组数据的方法
void Widget::update_exist_ArrayData()
{
    exist_data.clear(); // 先清空数组

    bool ok;
    quint8 station = ui->lineEdit_station->text().toUInt(&ok, 16);
    quint8 sid = ui->lineEdit_exist_description->text().toUInt(&ok, 16);
    quint16 data1 = ui->lineEdit_exist_data_1->text().toUInt(&ok, 16);
    quint16 data2 = ui->lineEdit_exist_data_2->text().toUInt(&ok, 16);

    // 以小端方式存储数据
    exist_data.append(static_cast<char>(station));
    exist_data.append(static_cast<char>(sid));

    exist_data.append(static_cast<char>(data1 & 0xFF)); // 低字节
    exist_data.append(static_cast<char>((data1 >> 8) & 0xFF)); // 高字节

    exist_data.append(static_cast<char>(data2 & 0xFF)); // 低字节
    exist_data.append(static_cast<char>((data2 >> 8) & 0xFF)); // 高字节

    // 计算CRC
    unsigned short crc = protocol->publicCalculateCRC(exist_data);
    // 使用小端格式存储CRC
    exist_data.append(static_cast<char>(crc & 0xFF)); // 先存储低字节
    exist_data.append(static_cast<char>((crc >> 8) & 0xFF)); // 然后存储高字节

    qDebug() << "复位命令数组刚写进数组的数据： "<<exist_data.toHex(); // 打印com_data的十六进制表示
}

//点击 复合指令1
void Widget::on_Button_compound_clicked()
{
    communicationManager->sengFlagTrue();
    // 验证消息格式
    if (protocol->validateMessageFormat(rest_data)) {
        qDebug() << "即将发送的复合指令1_data: " << rest_data.toHex();
        communicationManager->sendData(rest_data); // 发送 rest_data
        displayDataInLog(rest_data); // 将当前命令显示在数据日志的最上方
        compoundTimer->start(10); // 启动 compoundTimer，每10毫秒检查一次

        // 重置时间计数器
        compoundElapsedTimer.restart();

        // 使用 QTimer 循环
        //checkComTimer = new QTimer(this);
        checkComTimer->setInterval(10); // 每10毫秒检查一次
        connect(checkComTimer, &QTimer::timeout, this, &Widget::checkCompoundResponse); // 连接 checkTimer 的超时信号到 checkCompoundResponse 槽函数
        checkComTimer->start(); // 启动 checkTimer
    } else {
        qDebug() << "消息格式验证失败";
    }
}
//......................................................................................
//......................................................................................
//......................................................................................
//......................................................................................



//写入数据文件
void Widget::on_Button_write_clicked()
{
    // 打开文件对话框，选择文件
    QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "", tr("Files (*.hex *.bin)"));
    if (fileName.isEmpty()) {
        // 用户未选择文件，提示错误
        QMessageBox::critical(this, tr("Open Error"), tr("Invalid File"));
        return;
    }

    // 读取文件内容
    QFile file(fileName);
    if (!file.open(QIODevice::ReadOnly)) {
        // 文件打开失败，提示错误
        QMessageBox::critical(this, tr("File Error"), tr("Failed to open file"));
        return;
    }
    QByteArray fileData = file.readAll();
    file.close();

    // 获取站点号和描述符和分包个数
    bool ok;
    quint8 station = ui->lineEdit_station->text().toUInt(&ok, 16);
    if (!ok) {
        // 输入的站点号无效，提示错误
        QMessageBox::critical(this, tr("Input Error"), tr("Invalid station ID"));
        return;
    }
    quint8 sid = ui->lineEdit_write_description->text().toUInt(&ok, 16);
    if (!ok) {
        // 输入的描述符无效，提示错误
        QMessageBox::critical(this, tr("Input Error"), tr("Invalid description"));
        return;
    }

    quint8 count = ui->lineEdit_packet_count->text().toUInt(&ok, 16);
    if (!ok) {
        // 输入的分包个数无效，提示错误
        QMessageBox::critical(this, tr("Input Error"), tr("Invalid count"));
        return;
    }

    // 根据输入的站点号、描述符、分包个数和文件内容创建数据包
    packets = protocol->createPackets(station, sid, count, fileData);

    // 发送 flash_data
    communicationManager->sendData(flash_data);
    displayDataInLog(flash_data);

    loadFlashTimer->start(1000);
    checkTimer->start(30000);

}



//检查接收到的第一个数据包的响应
void Widget::checkFirstPacketResponse()
{
    // 获取单例的 Widget 实例
    Widget* widget = Widget::getInstance();

    if (!widget->responseForPacket.isEmpty()) {
        // 构造预期的响应内容
        QByteArray firstPacket = packets.first();
        QByteArray expectedResponse = firstPacket.left(7); // 站点号 + 标识符 + 起始地址 + 数据长度
        expectedResponse.append(firstPacket.right(2)); // CRC校验码

        // 比较接收到的响应与预期的响应
        if (widget->responseForPacket == expectedResponse) {
            loadFristDataTimer->stop();//关闭循环接收定时器
            checkTimer->stop();//关闭30S定时器
            qDebug() << "第一个数据包的响应与预期相同，发送剩余数据包";
            qDebug()<<"接收到第一个数据包响应后的packets"<<packets;
            // 发送剩余的数据包
            sendRemainingPackets();
        }
    }
}
//检查写入数据接受的 清除flash 响应，并决定是否发送下一个数据包
void Widget::checkFlashDataResponse()
{
    qDebug()<<"进入到写入数据接受清除flash的controlResponse为: "<<controlResponse;
    if (controlResponse == flash_data) {
        loadFlashTimer->stop();//接收到响应，关闭计时器
        checkTimer->stop();//关闭30S定时器
        qDebug() << "flash_data 与 responseForFlashData 相同，发送第一个数据包";
        if (!packets.isEmpty()) {
            // 发送第一个数据包
            communicationManager->sendData(packets.first());
            // 启动一个计时器等待第一个数据包的响应
            loadFristDataTimer->start(1000);
            checkTimer->start(30000);
        } else {
            // 没有创建数据包，提示错误
            QMessageBox::critical(this, tr("Packet Error"), tr("No packets created"));
        }
    }
}
//检查写入数据接收的 最后一个数据包 的响应
void Widget::checkLastPackResponse()
{
    Widget* widget = Widget::getInstance(); // 获取单例的Widget实例

    if (!widget->responseForPacket.isEmpty()) {
        QByteArray lastPacket = widget->packets.last();
        QByteArray expectedResponse = lastPacket.left(7); // 站点号 + 标识符 + 起始地址 + 数据长度
        expectedResponse.append(lastPacket.right(2)); // CRC校验码

        if (widget->responseForPacket == expectedResponse) {
            widget->loadLastDataTimer->stop();
            widget->checkTimer->stop();
            qDebug() << "接收到最后一个数据包的响应，发送成功";
            QMessageBox::information(this, tr("Transmit Completed"), tr("All packets have been sent successfully"));

            // 关闭提示信息
            if (widget->promptMessage) {
                widget->promptMessage->close();
                widget->promptMessage = nullptr;
            }
        }
    }
}

//发送剩余的数据包
void Widget::sendRemainingPackets()
{
    if (packets.isEmpty()) {
        qDebug() << "packets现在是空包";
        return;
    }

    // 显示提示信息
    promptMessage = new QMessageBox(QMessageBox::Information, tr("Transmitting"),
                                    tr("数据正在下发，请等待..."), QMessageBox::NoButton, this);
    promptMessage->setStandardButtons(QMessageBox::NoButton);
    promptMessage->show();

    for (const QByteArray& packet : packets) {
        communicationManager->sendData(packet);
        QThread::msleep(100); // 例如，100毫秒延迟
        qDebug() << "发送数据包:" << packet.toHex();
    }

    loadLastDataTimer->start(1000); // 1秒超时
    checkTimer->start(30000); // 30秒超时
    qDebug() << "等待最后一个数据包的响应";

}


//保存数据
void Widget::saveSettings()
{
    QSettings settings("MyCompany", "MyApp");
    bool ok;
    // 站点号+串口配置参数
    unsigned int station = ui->lineEdit_station->text().toUInt(&ok, 16);
    if (ok) settings.setValue("lineEdit_station", station);
    settings.setValue("lineEdit_com", ui->lineEdit_com->text());
    settings.setValue("lineEdit_rate", ui->lineEdit_rate->text());
    settings.setValue("lineEdit_parity_bit", ui->lineEdit_parity_bit->text());
    settings.setValue("lineEdit_data_bit", ui->lineEdit_data_bit->text());
    settings.setValue("lineEdit_stop_bit", ui->lineEdit_stop_bit->text());
    // 复位命令配置参数
    unsigned int rest_description = ui->lineEdit_rest_description->text().toUInt(&ok, 16);
    if (ok) settings.setValue("lineEdit_rest_description", rest_description);
    unsigned int rest_dat_1 = ui->lineEdit_rest_dat_1->text().toUInt(&ok, 16);
    if (ok) settings.setValue("lineEdit_rest_dat_1", rest_dat_1);
    unsigned int rest_dat_2 = ui->lineEdit_rest_dat_2->text().toUInt(&ok, 16);
    if (ok) settings.setValue("lineEdit_rest_dat_2", rest_dat_2);
    // 更新命令配置参数
    unsigned int com_des = ui->lineEdit_com_des->text().toUInt(&ok, 16);
    if (ok) settings.setValue("lineEdit_com_des", com_des);
    unsigned int com_data_1 = ui->lineEdit_com_data_1->text().toUInt(&ok, 16);
    if (ok) settings.setValue("lineEdit_com_data_1", com_data_1);
    unsigned int com_data_2 = ui->lineEdit_com_data_2->text().toUInt(&ok, 16);
    if (ok) settings.setValue("lineEdit_com_data_2", com_data_2);
    // 清除Flash配置参数
    unsigned int flash_description = ui->lineEdit_flash_description->text().toUInt(&ok, 16);
    if (ok) settings.setValue("lineEdit_flash_description", flash_description);
    unsigned int flash_data_1 = ui->lineEdit_falsh_data_1->text().toUInt(&ok, 16);
    if (ok) settings.setValue("lineEdit_falsh_data_1", flash_data_1);
    unsigned int flash_data_2 = ui->lineEdit_falsh_data_2->text().toUInt(&ok, 16);
    if (ok) settings.setValue("lineEdit_falsh_data_2", flash_data_2);
    // 测试存在配置参数
    unsigned int exist_description = ui->lineEdit_exist_description->text().toUInt(&ok, 16);
    if (ok) settings.setValue("lineEdit_exist_description", exist_description);
    unsigned int exist_data_1 = ui->lineEdit_exist_data_1->text().toUInt(&ok, 16);
    if (ok) settings.setValue("lineEdit_exist_data_1", exist_data_1);
    unsigned int exist_data_2 = ui->lineEdit_exist_data_2->text().toUInt(&ok, 16);
    if (ok) settings.setValue("lineEdit_exist_data_2", exist_data_2);
    // 载入数据配置参数
    unsigned int write_description = ui->lineEdit_write_description->text().toUInt(&ok, 16);
    if (ok) settings.setValue("lineEdit_write_description", write_description);
    unsigned int packet_count = ui->lineEdit_packet_count->text().toUInt(&ok, 16);
    if (ok) settings.setValue("lineEdit_packet_count", packet_count);


}
//加载数据
void Widget::loadSettings()
{
    QSettings settings("MyCompany", "MyApp");
    bool ok;
    // 站点号+串口配置参数
    unsigned int station = settings.value("lineEdit_station",0).toInt(&ok);
    if(ok)ui->lineEdit_station->setText(QString::number(station, 16).rightJustified(2, '0'));
    ui->lineEdit_com->setText(settings.value("lineEdit_com", "").toString());
    ui->lineEdit_rate->setText(settings.value("lineEdit_rate", "").toString());
    ui->lineEdit_parity_bit->setText(settings.value("lineEdit_parity_bit", "").toString());
    ui->lineEdit_data_bit->setText(settings.value("lineEdit_data_bit", "").toString());
    ui->lineEdit_stop_bit->setText(settings.value("lineEdit_stop_bit", "").toString());
    // 复位命令配置参数
    unsigned int rest_description = settings.value("lineEdit_rest_description", 0).toUInt(&ok);
    if (ok) ui->lineEdit_rest_description->setText(QString::number(rest_description, 16).rightJustified(2, '0'));
    unsigned int rest_dat_1 = settings.value("lineEdit_rest_dat_1", 0).toUInt(&ok);
    if (ok) ui->lineEdit_rest_dat_1->setText(QString::number(rest_dat_1, 16).rightJustified(2, '0'));
    unsigned int rest_dat_2 = settings.value("lineEdit_rest_dat_2", 0).toUInt(&ok);
    if (ok) ui->lineEdit_rest_dat_2->setText(QString::number(rest_dat_2, 16).rightJustified(2, '0'));
    // 更新命令配置参数
    unsigned int com_des = settings.value("lineEdit_com_des", 0).toUInt(&ok);
    if (ok) ui->lineEdit_com_des->setText(QString::number(com_des, 16).rightJustified(2, '0'));
    unsigned int com_data_1 = settings.value("lineEdit_com_data_1", 0).toUInt(&ok);
    if (ok) ui->lineEdit_com_data_1->setText(QString::number(com_data_1, 16).rightJustified(2, '0'));
    unsigned int com_data_2 = settings.value("lineEdit_com_data_2", 0).toUInt(&ok);
    if (ok) ui->lineEdit_com_data_2->setText(QString::number(com_data_2, 16).rightJustified(2, '0'));
    // 清除Flash配置参数
    unsigned int flash_description = settings.value("lineEdit_flash_description", 0).toUInt(&ok);
    if (ok) ui->lineEdit_flash_description->setText(QString::number(flash_description, 16).rightJustified(2, '0'));
    unsigned int flash_data_1 = settings.value("lineEdit_falsh_data_1", 0).toUInt(&ok);
    if (ok) ui->lineEdit_falsh_data_1->setText(QString::number(flash_data_1, 16).rightJustified(2, '0'));
    unsigned int flash_data_2 = settings.value("lineEdit_falsh_data_2", 0).toUInt(&ok);
    if (ok) ui->lineEdit_falsh_data_2->setText(QString::number(flash_data_2, 16).rightJustified(2, '0'));
    // 测试存在配置参数
    unsigned int exist_description = settings.value("lineEdit_exist_description", 0).toUInt(&ok);
    if (ok) ui->lineEdit_exist_description->setText(QString::number(exist_description, 16).rightJustified(2, '0'));
    unsigned int exist_data_1 = settings.value("lineEdit_exist_data_1", 0).toUInt(&ok);
    if (ok) ui->lineEdit_exist_data_1->setText(QString::number(exist_data_1, 16).rightJustified(2, '0'));
    unsigned int exist_data_2 = settings.value("lineEdit_exist_data_2", 0).toUInt(&ok);
    if (ok) ui->lineEdit_exist_data_2->setText(QString::number(exist_data_2, 16).rightJustified(2, '0'));
    // 载入数据配置参数
    unsigned int write_description = settings.value("lineEdit_write_description", 0).toUInt(&ok);
    if (ok) ui->lineEdit_write_description->setText(QString::number(write_description, 16).rightJustified(2, '0'));
    unsigned int packet_count = settings.value("lineEdit_packet_count", 0).toUInt(&ok);
    if (ok) ui->lineEdit_packet_count->setText(QString::number(packet_count, 16).rightJustified(2, '0'));
}
//关闭所有计时器
void Widget::stopAndDeleteTimer(QTimer *&timer)
{
    if (timer) {
        if (timer->isActive()) {
            timer->stop();
        }
        delete timer;
        timer = nullptr;
    }
}
